package com.ruoyi.partybuilding.service.impl;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Predicate;

import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.partybuilding.common.DataUtil;
import com.ruoyi.partybuilding.common.EQuery.IDeptEntity;
import com.ruoyi.partybuilding.common.EQueryHelper;
import com.ruoyi.partybuilding.common.PageSort;
import com.ruoyi.partybuilding.domain.SysDeptRef;
import com.ruoyi.partybuilding.domain.UserMemberDeptV;
import com.ruoyi.partybuilding.domain.vo.DeptOrgVo;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import com.ruoyi.partybuilding.mapper.OrgMapper;
import com.ruoyi.partybuilding.domain.Org;
import com.ruoyi.partybuilding.service.IOrgService;

import javax.annotation.Resource;

/**
 * 组织信息Service业务层处理
 * 
 * @author he-liangliang@outlook.com
 * @date 2024-11-27
 */
@Service
public class OrgServiceImpl implements IOrgService 
{
    @Autowired
    private OrgMapper orgMapper;
    @Resource
    protected EQueryHelper queryHelper;

    //部门：非删除党员数统计
    String sql="SELECT de.*,te.num stat_team_person from ( SELECT dept.*,sum(deptNum.num) stat_member from sys_dept dept left join ( select d.dept_id,max(d.dept_name),MAX(d.ancestors) ancestors,count(1) num,max(u.user_id) from sys_dept d left join v_user_member_dept u ON u.dept_id = d.dept_id and u.del_flag=0 and u.id is not null where u.user_id is not null GROUP BY d.dept_id ) deptNum on find_in_set(dept.dept_id,deptNum.ancestors) or dept.dept_id=deptNum.dept_id GROUP BY dept.dept_id ) de left join ( select newTeam.*,tp.* from ( select * from pb_team_record t where year= ( select max(`year`) from pb_team_record GROUP BY dept_id HAVING dept_id=t.dept_id) and DATE_ADD(t.trans_time,INTERVAL t.`year` year)>NOW() ) newTeam left join ( select team_id,count(1) num from pb_team_person GROUP BY team_id ) tp on tp.team_id=newTeam.id ) te on de.dept_id=te.dept_id where 1=1";

    /** 统计下级党员、班子，人数;部门：非删除党员数统计
     *
     * @param whereObj
     * @return
     */
   public R<List<DeptOrgVo>> deptInfoStat(DeptOrgVo whereObj) {

        var list = queryHelper.CreateItems(sql)
                .and("del_flag=?",0)
                .andNotNull("de.dept_id=?", whereObj.getDeptId())
                .resultPkg().sqlQuery(DeptOrgVo.class);
        return R.ok(list);
    }
    public <T extends IDeptEntity> void deptSet(Collection<T> list, BiConsumer<DeptOrgVo,T> predicate){
        var orgList= deptVoList(null);
        list.forEach(p->{
                var tmp = orgList.getData().stream().filter(x -> Objects.equals(x.getDeptId(), p.getDeptId())).findFirst();
                tmp.ifPresent(z -> predicate.accept(tmp.get(),p));
        });
    }
    public <T extends IDeptEntity> List<Map> deptSetToMap(Collection<T> list,String deptNameStr) {
        if (StringUtils.isBlank(deptNameStr))
            deptNameStr = "deptName";
        var orgList = deptVoList(null);
        var maps = new ArrayList<Map>();
        String finalDeptNameStr = deptNameStr;
        list.forEach(p -> {
            var tmp = orgList.getData().stream().filter(x -> Objects.equals(x.getDeptId(), p.getDeptId())).findFirst();
            var map = DataUtil.toMap(p, null);
            tmp.ifPresent(z -> map.put(finalDeptNameStr, z.getDeptName()));
            maps.add(map);
        });
        return maps;
    }
    public R<List<DeptOrgVo>> deptVoList(DeptOrgVo entity) {
        var re = deptVoList(entity, PageSort.toMaxSize());
        return R.ok(re.getData().getContent());
    }
    public R<Page<DeptOrgVo>> deptVoList(DeptOrgVo entity, PageSort page) {
        var re = queryHelper.query().queryable(SysDeptRef.class).leftJoin(Org.class, (p, p2) -> p.eq(p2, SysDept::getDeptId, Org::getDeptId))
                .select(DeptOrgVo.class, (t, t2) -> {
                    t2.columnAll();
                    t2.columnIgnore(Org::getDeptId);
                    t2.columnIgnore(Org::getDeptName);
                    t.columnAll();
                })
                .where(entity == null || StringUtils.isBlank(entity.getDelFlag()), p -> p.eq(DeptOrgVo::getDelFlag, "0"))
                .whereObject(entity != null, entity)
                .orderByObject(page != null && page.orderByIs(), page)
                .toPageResult(page.getPageNum(), page.getPageSize());

        return R.ok(PageSort.toPageData(re));
    }
    public R<DeptOrgVo> deptVoGet(long deptId) {
        var whereObj = new DeptOrgVo();
        whereObj.setDeptId(deptId);
        var re = deptVoList(whereObj);
        if (!R.isSuccess(re))
            return (R) re;
        if (re.getData().size() < 1)
            return R.ok(null);
        return R.ok(re.getData().get(0));
    }

      public R<List<DeptOrgVo>> queryAndSubs(long deptId) {
          var re = queryHelper.query().queryable(SysDept.class).leftJoin(Org.class, (p, p2) -> p.eq(p2, SysDept::getDeptId, Org::getDeptId))
                  .select(DeptOrgVo.class, (t, t2) -> {
                      t2.columnAll();
                      t2.columnIgnore(Org::getDeptId);
                      t2.columnIgnore(Org::getDeptName);
                      t.columnAll();
                  }).where( p ->
                          p.and(x-> x.eq(DeptOrgVo::getDeptId, deptId).or().sqlNativeSegment("FIND_IN_SET({0},{1})", z -> z.value(deptId).expression(DeptOrgVo::getAncestors)))
                  ).toList();
          return R.ok(re);
      }
    public R<List<DeptOrgVo>> allChilds(long deptId) {
        var re = queryHelper.query().queryable(SysDept.class).leftJoin(Org.class, (p, p2) -> p.eq(p2, SysDept::getDeptId, Org::getDeptId))
                .select(DeptOrgVo.class, (t, t2) -> {
                    t2.columnAll();
                    t2.columnIgnore(Org::getDeptId);
                    t2.columnIgnore(Org::getDeptName);
                    t.columnAll();
                }).where(p->{
                    p.sqlNativeSegment("FIND_IN_SET({0},{1})",x->x.value(deptId).expression(DeptOrgVo::getAncestors));

                }).toList();
        return R.ok(re);
    }
    /**
     * 查询组织信息
     * 
     * @param id 组织信息主键
     * @return 组织信息
     */
    @Override
    public Org selectOrgById(Long id)
    {
        return orgMapper.selectOrgById(id);
    }

    /**
     * 查询组织信息列表
     * 
     * @param org 组织信息
     * @return 组织信息
     */
    @Override
    public List<Org> selectOrgList(Org org)
    {
        return orgMapper.selectOrgList(org);
    }

    /**
     * 新增组织信息
     * 
     * @param org 组织信息
     * @return 结果
     */
    @Override
    public int insertOrg(Org org)
    {
        return orgMapper.insertOrg(org);
    }

    /**
     * 修改组织信息
     * 
     * @param org 组织信息
     * @return 结果
     */
    @Override
    public int updateOrg(Org org)
    {
        return orgMapper.updateOrg(org);
    }

    /**
     * 批量删除组织信息
     * 
     * @param ids 需要删除的组织信息主键
     * @return 结果
     */
    @Override
    public int deleteOrgByIds(Long[] ids)
    {
        return orgMapper.deleteOrgByIds(ids);
    }

    /**
     * 删除组织信息信息
     * 
     * @param id 组织信息主键
     * @return 结果
     */
    @Override
    public int deleteOrgById(Long id)
    {
        return orgMapper.deleteOrgById(id);
    }
}
